package reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Test01 {
    public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class cls1 = Student.class;
        System.out.println("Student类模板：" + cls1);

        Student student = new Student();
        Class cls2 = student.getClass();
        System.out.println("Student类模板：" + cls2);

        String str = "reflect.Student";
        try {
            Class cls3 = Class.forName(str);
            System.out.println("Student类模板：" + cls3);
            System.out.println(cls1 == cls2);
            System.out.println(cls1 == cls3);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        // 通过反射获取类中公共的属性
//        Field field = cls1.getField("name");
//        Field [] fields = cls1.getFields();
//        System.out.println("field:" + field);
//        System.out.println("fields:" + Arrays.toString(fields));

        // 通过反射获取类中所有的属性
        Field field = cls1.getDeclaredField("name");
        Field [] fields = cls1.getDeclaredFields();
        System.out.println("field:" + field);
        System.out.println("fields:" + Arrays.toString(fields));

        // 通过反射获取类中所有的方法
        Method method = cls1.getDeclaredMethod("introduce");
        Method [] methods = cls1.getDeclaredMethods();
        Method [] methods1 = cls1.getMethods();
        System.out.println("method:" + method);
        System.out.println("methods:" + Arrays.toString(methods));
        System.out.println("methods1:" + Arrays.toString(methods1));

        // 通过反射获取类中的构造方法
        Constructor constructor = cls1.getDeclaredConstructor(Integer.class,String.class,Integer.class);
        Constructor [] constructors = cls1.getDeclaredConstructors();
        System.out.println("constructor:" + constructor);
        System.out.println("constructors:" + Arrays.toString(constructors));

        // 通过反射API产生对象
        Object obj = constructor.newInstance(1,"张三",30);
        System.out.println("student:" + obj);

        // 通过反射API执行方法
        method.invoke(obj);

        // 通过反射API获取属性
        // 设置私有属性允许被访问
        field.setAccessible(true);
        String name = field.get(obj).toString();
        System.out.println("name:" + name);

        field.set(obj,"李四");
        method.invoke(obj);


    }
}
